

#include <memory.h>
#include <util.h>

unsigned int *__kernel_page_dir;
unsigned int __total_memory = 0;

/* A few utility functions for writing memory tables */
unsigned int _mem_make_page_dir_entry(unsigned int);
void _mem_make_page_table(unsigned int *, unsigned int, unsigned int);
unsigned int _mem_make_page_table_entry(unsigned int, unsigned int);
void _print_page_table_entry(unsigned int);

int __init_kernel_mem(){

  if (__total_memory == 0) return 1;

  unsigned int page_dir_addr = __KERNEL_PAGES - 4096;
  __kernel_page_dir = (unsigned int *) page_dir_addr;

  /* Make kernel page dir table */
  int i;
  for ( i = 0; i < 1024; i++){
    __kernel_page_dir[i] = _mem_make_page_dir_entry(
				    (i * 4096) + __KERNEL_PAGES);
  }

  /* Populate the page dir entries. */
  for ( i = 0; i < 1024; i++){
    _mem_make_page_table((unsigned int *)((i * 4096) + __KERNEL_PAGES), 
			 i * 0x400000, 3);
  }
  
  _write_cr3((unsigned int)__kernel_page_dir);
  //_print_page_table_entry(__kernel_page_dir[0]);
  //_print_page_table_entry(*(unsigned int *)(__KERNEL_PAGES + 4096));
  _write_cr0(_read_cr0() | 0x80000000);
  
  return 0;

}

unsigned int _mem_make_page_dir_entry(unsigned int base_addr){

  unsigned int page_dir = 0;
  page_dir = base_addr;
  page_dir |= 3;
  return page_dir;

}

void _mem_make_page_table(unsigned int *loc, 
			  unsigned int mem_start, unsigned int flags){

  int i;
  for ( i = 0; i < 1024; i++){
    loc[i] = _mem_make_page_table_entry(mem_start + (4096 * i), flags);
  }

}

unsigned int _mem_make_page_table_entry(unsigned int mem_start, 
					unsigned int flags){

  unsigned int page_entry = 0;
  page_entry = mem_start;
  page_entry |= flags;
  return page_entry;

}

void _print_page_table_entry(unsigned int entry){

  k_print("  Page Table Entry: ");
  char buf[33];
  itobs(entry, buf);
  k_print(buf);
  k_printl();

}
